<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :title="getTitle"
    width="70%"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm" />

    <BasicTable @register="registerTable" v-if="isCustom == 1" class="dataAuthDrag !mb-5">
      <template #toolbar>
        <a-button type="primary" @click="handleCreate"> {{ t('添加过滤条件') }} </a-button>
      </template>
      <template #bodyCell="{ column, text, record }">
        <template
          v-if="
            ['drag', 'fieldName', 'fieldType', 'fieldValue', 'conditionType'].includes(
              column.dataIndex,
            )
          "
        >
          <div>
            <Icon class="mover" icon="ant-design:drag-outlined" v-if="column.dataIndex == 'drag'" />

            <a-select
              class="w-full"
              :placeholder="t('请选择')"
              v-else-if="column.dataIndex == 'conditionType'"
              v-model:value="record[column.dataIndex]"
            >
              <a-select-option :value="0">{{ t('等于') }}</a-select-option>
              <a-select-option :value="1">{{ t('大于') }}</a-select-option>
              <a-select-option :value="2">{{ t('大于等于') }}</a-select-option>
              <a-select-option :value="3">{{ t('小于') }}</a-select-option>
              <a-select-option :value="4">{{ t('小于等于') }}</a-select-option>
              <a-select-option :value="5">{{ t('包含') }}</a-select-option>
              <a-select-option :value="6">{{ t('包含于') }}</a-select-option>
              <a-select-option :value="7">{{ t('不等于') }}</a-select-option>
              <a-select-option :value="8">{{ t('不包含') }}</a-select-option>
              <a-select-option :value="9">{{ t('不包含于') }}</a-select-option>
            </a-select>
            <a-input
              v-if="column.dataIndex == 'fieldName'"
              v-model:value="record[column.dataIndex]"
              :placeholder="t('请填写字段名')"
            />
            <a-select
              class="w-full"
              :placeholder="t('请选择字段类型')"
              v-else-if="column.dataIndex == 'fieldType'"
              v-model:value="record[column.dataIndex]"
              @change="(_, option) => changeFieldType(record, option)"
            >
              <a-select-option :value="0">{{ t('文本(String)') }}</a-select-option>
              <a-select-option :value="1">{{ t('文本(Int)') }}</a-select-option>
              <a-select-option :value="2" :label="t('登录人ID')">{{
                t('登录人ID')
              }}</a-select-option>
              <a-select-option :value="3" :label="t('登录人组织架构')">{{
                t('登录人组织架构')
              }}</a-select-option>
              <a-select-option :value="4" :label="t('登录人所属组织架构及下属组织架构')">{{
                t('登录人所属组织架构及下属组织架构')
              }}</a-select-option>
              <a-select-option :value="5" :label="t('登录人账号')">{{
                t('登录人账号')
              }}</a-select-option>
              <a-select-option :value="6" :label="t('登录人岗位')">{{
                t('登录人岗位')
              }}</a-select-option>
              <a-select-option :value="7" :label="t('登录人角色')">{{
                t('登录人角色')
              }}</a-select-option>
            </a-select>
            <a-input
              v-else-if="column.dataIndex == 'fieldValue'"
              v-model:value="record[column.dataIndex]"
              :placeholder="
                record['fieldType'] === undefined ? t('请先选择字段类型') : t('请填写字段值')
              "
              :disabled="record['fieldType'] > 1"
              :readonly="record['fieldType'] === undefined"
            />
          </div>
        </template>
        <template v-else-if="column.dataIndex == 'action'">
          <TableAction
            :actions="[
              {
                icon: 'ant-design:delete-outlined',
                color: 'error',
                title: t('删除'),
                popConfirm: {
                  title: t('是否确认删除'),
                  confirm: handleDelete.bind(null, record),
                },
              },
            ]"
          />
        </template>
        <template v-else> {{ text }} </template>
      </template>
    </BasicTable>

    <a-form
      :model="formState"
      name="basic"
      autocomplete="off"
      :label-col="{ style: { width: '100px' } }"
    >
      <a-form-item name="authFormula" v-if="isCustom == 1">
        <template #label>
          <Tooltip color="rgba(0,0,0,0.9)" :overlayStyle="{ maxWidth: '448px' }">
            <template #title>
              <div class="tipdiv">
                <p>{{ t('请按如下规则编辑条件组合') }}</p>
                <p
                  >{{ t('正确示例: (1 and 2) or (3 and 4)') }}
                  <Icon icon="ant-design:check-circle-outlined" color="green"
                /></p>
                <p>{{ t('1.有and和or必须加括号') }}</p>
                <p class="text-[pink]"
                  >{{ t('错误示例:1 and 2 or 3 and 4') }}
                  <Icon icon="ant-design:close-circle-outlined" color="pink"
                /></p>
                <p>{{ t('2.一个括号里不能同时出现and和or') }}</p>
                <p class="text-[pink]"
                  >{{ t('错误示例: (1 and 2 or 3 )and 4') }}
                  <Icon icon="ant-design:close-circle-outlined" color="pink" />
                </p>
                <p>{{ t('3.不允许出现不存在的编号') }}</p>
                <p class="text-[pink]"
                  >{{ t('错误示例: 1 and 2 and 3 and 4 and 5') }}
                  <Icon icon="ant-design:close-circle-outlined" color="pink"
                /></p>
                <p>{{ t('4.括号都是成对出现的') }}</p>
                <p class="text-[pink]"
                  >{{ t('错误示例: (1 and 2 and 3 and 4') }}
                  <Icon icon="ant-design:close-circle-outlined" color="pink"
                /></p>
              </div>
            </template>
            <Icon icon="ant-design:question-circle-twotone" />
          </Tooltip>
          {{ t('组合公式') }}
        </template>
        <a-textarea
          v-model:value="formState.authFormula"
          :placeholder="
            t(
              '请填写组合公式,组合公式非必填，如果不填写，则按照已有条件并列执行，例如：1 and 2 and 3 and 4,填写后，按照填写的公式进行执行',
            )
          "
        />
      </a-form-item>

      <a-form-item :label="t('备注')" name="remark">
        <a-textarea v-model:value="formState.remark" :placeholder="t('请输入备注')" />
      </a-form-item>
    </a-form>
  </BasicDrawer>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, reactive, h, watch, nextTick } from 'vue';
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import { BasicTable, useTable, TableAction, BasicColumn } from '/@/components/Table';

  import { Tooltip } from 'ant-design-vue';

  import { useMessage } from '/@/hooks/web/useMessage';
  // import { useI18n } from 'vue-i18n';

  import Sortable from 'sortablejs';
  import { getRoleAllList } from '/@/api/system/role';
  import SelectUser from '/@/components/Form/src/components/SelectUser.vue';
  import { Icon } from '/@/components/Icon';
  import { isNullAndUnDef } from '/@/utils/is';

  import { addAuth, updateAuth } from '/@/api/system/authorize';
  import { useI18n } from '/@/hooks/web/useI18n';
  const { t } = useI18n();
  export const formSchema: FormSchema[] = [
    {
      field: 'code',
      label: t('权限编码'),
      component: 'Input',
      required: true,
      colProps: { lg: 24, md: 24 },
    },
    {
      field: 'name',
      label: t('名称'),
      component: 'Input',
      required: true,
      colProps: { lg: 24, md: 24 },
    },
    {
      field: 'authType',
      label: t('对象类型'),
      component: 'Select',
      required: true,
      defaultValue: 0,
      colProps: { lg: 24, md: 24 },
      componentProps: {
        options: [
          {
            label: t('角色'),
            value: 0,
          },
          {
            label: t('用户'),
            value: 1,
          },
        ],
      },
    },
    {
      field: 'objectIdList',
      label: t('授权对象'),
      component: 'Input',
      required: true,
      colProps: { lg: 24, md: 24 },
      render: ({ model, field }) => {
        return h(SelectUser, {
          placeholder: t('请选择授权对象'),
          value: model[field],
          suffix: 'ant-design:ellipsis-outlined',
          onSelectedId: (v) => {
            model[field] = v;
          },
        });
      },
      ifShow: ({ values }) => {
        return values.authType == 1;
      },
    },
    {
      field: 'objectId',
      label: t('授权对象'),
      component: 'Select',
      required: true,
      colProps: { lg: 24, md: 24 },
      componentProps: {
        options: [],
        'filter-option': null,
        mode: 'multiple',
        'show-search': true,
        fieldNames: {
          label: 'name',
          value: 'id',
        },
      },
      ifShow: ({ values }) => {
        return values.authType != 1;
      },
    },
    {
      field: 'authMethod',
      label: t('授权方式'),
      component: 'Select',
      defaultValue: 0,
      required: true,
      componentProps: {
        options: [
          {
            label: t('简易模式'),
            value: 0,
          },
          {
            label: t('自定义配置'),
            value: 1,
          },
        ],
        onChange: (v) => {
          isCustom.value = v;
        },
      },
      colProps: { lg: 24, md: 24 },
    },

    {
      field: 'authScope',
      label: t('实现范围'),
      component: 'Select',
      required: true,
      componentProps: {
        options: [
          {
            label: t('仅查看登录人数据'),
            value: 0,
          },
          {
            label: t('仅查看登录人同岗位数据'),
            value: 1,
          },
          {
            label: t('仅查看登录人及所有下属岗位数据'),
            value: 2,
          },
          {
            label: t('仅查看登录人同岗位及所有下属岗位数据'),
            value: 3,
          },
          {
            label: t('仅查看登录人同组织架构人员数据'),
            value: 4,
          },
          {
            label: t('仅查看登录人及所有下属组织架构人员数据'),
            value: 5,
          },
          {
            label: t('仅查看登录人同组织架构人员及所有下属组织架构人员数据'),
            value: 6,
          },
          {
            label: t('仅查看登录人同角色数据'),
            value: 7,
          },
        ],
      },
      colProps: { lg: 24, md: 24 },
      ifShow: ({ values }) => {
        return values.authMethod === 0;
      },
    },
  ];

  export const columns: BasicColumn[] = [
    {
      title: '',
      dataIndex: 'drag',
      width: 50,
    },
    {
      title: t('序号'),
      dataIndex: 'orderNumber',
      width: 50,
    },
    {
      title: t('字段名'),
      dataIndex: 'fieldName',
      width: 100,
    },
    {
      title: t('条件'),
      dataIndex: 'conditionType',
      width: 100,
    },
    {
      title: t('字段类型'),
      dataIndex: 'fieldType',
      width: 200,
    },
    {
      title: t('字段值'),
      dataIndex: 'fieldValue',
      width: 180,
    },
  ];
  interface FormState {
    authFormula: string;
    remark: string;
  }
  interface DataItem {
    key?: string;
    orderNumber: number;
    fieldName: string;
    conditionType: number;
    fieldType?: number;
    fieldValue: string;
  }
  const isCustom = ref<number>(0);
  const editableData = ref<DataItem[]>([]);
  const selectUser = ref<boolean>(false);
  export default defineComponent({
    name: 'MenuDrawer',
    components: {
      BasicDrawer,
      BasicForm,
      TableAction,
      BasicTable,
      Tooltip,
      Icon,
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const isUpdate = ref(true);
      const { notification } = useMessage();
      const rowId = ref('');
      const formState = reactive<FormState>({
        authFormula: '',
        remark: '',
      });

      watch(
        () => editableData.value,
        (val) => {
          if (val && val.length) {
            nextTick(() => {
              const tbody: any = document.querySelector('.dataAuthDrag .ant-table-tbody');
              const tr: any = tbody.querySelector('tr.ant-table-row[draggable="false"]');
              if (tr) tr.remove();
              Sortable.create(tbody, {
                handle: '.mover',

                onEnd: (evt) => {
                  const { oldIndex, newIndex } = evt;
                  if (
                    isNullAndUnDef(oldIndex) ||
                    isNullAndUnDef(newIndex) ||
                    oldIndex === newIndex
                  ) {
                    return;
                  }

                  let columns: DataItem[] = getDataSource();

                  setTableData([]);

                  editableData.value = [];
                  nextTick(() => {
                    let old = columns[oldIndex - 1];
                    columns.splice(oldIndex - 1, 1);
                    columns.splice(newIndex - 1, 0, old);
                    columns.forEach((o, i) => {
                      o.orderNumber = i + 1;
                    });
                    editableData.value = columns;
                    setTableData(editableData.value);
                  });
                },
              });
            });
          }
        },
        {
          deep: true,
        },
      );

      watch(isCustom, (val) => {
        if (val === 1) {
          //首次进入清除自定义表格内容
          nextTick(() => {
            setTableData(editableData.value);
          });
        }
      });

      const [registerForm, { resetFields, setFieldsValue, updateSchema, validate }] = useForm({
        labelWidth: 100,
        schemas: formSchema,
        showActionButtonGroup: false,
        baseColProps: { lg: 12, md: 24 },
      });
      const [registerTable, { getDataSource, setTableData }] = useTable({
        title: '',
        dataSource: editableData.value,
        columns,
        pagination: false,
        striped: false,
        useSearchForm: false,
        bordered: true,
        showIndexColumn: false,
        canResize: false,
        rowKey: 'id',
        actionColumn: {
          width: 80,
          title: t('操作'),
          dataIndex: 'action',
          slots: { customRender: 'action' },
          fixed: undefined,
        },
      });
      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
        resetFields();
        setDrawerProps({ confirmLoading: false });
        isUpdate.value = !!data?.isUpdate;
        editableData.value = [];
        const treeData = await getRoleAllList();
        const filterOption = (input: string, option: any) => {
          return option.name.indexOf(input) >= 0;
        };
        updateSchema({
          field: 'objectId',
          componentProps: { options: treeData, 'filter-option': filterOption },
        });
        if (unref(isUpdate)) {
          rowId.value = data.record.id;
          let arrData: string[] = [];
          data.record.authObjectList.forEach((o) => {
            arrData.push(o.objectId);
          });
          if (data.record.authType == 1) {
            data.record.objectIdList = arrData.join(',');
          } else {
            data.record.objectId = arrData;
          }
          setFieldsValue({
            ...data.record,
          });
          isCustom.value = data.record.authMethod;
          formState.remark = data.record.remark;
          if (isCustom.value == 1) {
            formState.authFormula = data.record.authFormula;
            editableData.value = data.record.authConfigList;
            nextTick(() => {
              setTableData(editableData.value);
            });
          }
        } else {
          isCustom.value = 0;
        }
      });

      function handleCreate() {
        let dataSource: DataItem[] = getDataSource();
        let obj = {
          orderNumber: dataSource.length + 1,
          fieldName: '',
          conditionType: 0,
          fieldValue: '',
        };
        dataSource.push(obj);
        editableData.value = dataSource;
        setTableData(dataSource);
      }

      function changeFieldType(record: Recordable, option) {
        record.fieldValue = record.fieldType > 1 ? option.label : '';
      }

      function handleDelete(record: Recordable) {
        const dataSource: DataItem[] = getDataSource();
        editableData.value = [];
        dataSource.forEach((o) => {
          if (o.orderNumber < record.orderNumber) {
            editableData.value.push(o);
          } else if (o.orderNumber > record.orderNumber) {
            o.orderNumber -= 1;
            editableData.value.push(o);
          }
        });
        setTableData(editableData.value);
      }

      const getTitle = computed(() => (!unref(isUpdate) ? t('新增数据权限') : t('编辑数据权限')));

      async function handleSubmit() {
        try {
          const values = await validate();
          if (values.authType == 1) {
            values.objectIdList = values.objectIdList.split(',');
          } else {
            values.objectIdList = values.objectId;
          }
          if (values.authMethod == 1) {
            values.authConfigList = getDataSource();
            Object.assign(values, formState);
          } else {
            values.remark = formState.remark;
          }

          setDrawerProps({ confirmLoading: true });
          // TODO custom api
          if (!unref(isUpdate)) {
            //false 新增
            await addAuth(values);
            notification.success({
              message: t('提示'),
              description: t('新增成功'),
            }); //提示消息
          } else {
            values.id = rowId.value;
            await updateAuth(values);
            notification.success({
              message: t('提示'),
              description: t('编辑成功'),
            }); //提示消息
          }
          closeDrawer();
          emit('success');
        } catch (error) {
          setDrawerProps({ confirmLoading: false });
        }
      }

      return {
        registerDrawer,
        registerForm,
        editableData,
        formState,
        getTitle,
        isCustom,
        selectUser,
        handleSubmit,
        registerTable,
        handleCreate,
        changeFieldType,
        handleDelete,
        t,
      };
    },
  });
</script>
<style scoped>
  .tipdiv p {
    margin: 0;
  }
</style>
